<!--
 * @copyright 2025 银杏ERP
 * @author 银杏ERP
 * @version 1.0
 * @license http://www.hhyx.xyz
 * @developer Lhf
-->

<template>
  <div class="trend-chart-card">
    <div class="chart-header">
      <h3>采购趋势分析</h3>
      <div class="view-controls">
        <el-radio-group v-model="currentView" size="small" @change="handleViewChange">
          <el-radio-button label="amount">采购金额</el-radio-button>
          <el-radio-button label="count">采购单量</el-radio-button>
          <el-radio-button label="savings">节约成本</el-radio-button>
        </el-radio-group>
      </div>
    </div>
    
    <div class="chart-container">
      <div class="chart-wrapper" ref="chartRef"></div>
      <div v-if="loading" class="chart-loading">
        <el-skeleton :rows="6" animated />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watch, onMounted, PropType, onBeforeUnmount, computed } from 'vue'
import * as echarts from 'echarts/core'
import { LineChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  ToolboxComponent,
  DataZoomComponent
} from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'

// 注册必要的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  ToolboxComponent,
  DataZoomComponent,
  LineChart,
  CanvasRenderer
])

// 数据类型定义
interface ChartDataItem {
  date: string
  amount: number
  count: number
  savings: number
}

type ViewType = 'amount' | 'count' | 'savings'

export default defineComponent({
  name: 'PurchaseTrendChart',
  props: {
    chartData: {
      type: Array as PropType<ChartDataItem[]>,
      required: true
    },
    loading: {
      type: Boolean,
      default: false
    },
    viewType: {
      type: String as PropType<ViewType>,
      default: 'amount'
    }
  },
  emits: ['view-change'],
  setup(props, { emit }) {
    const chartRef = ref<HTMLElement | null>(null)
    let chartInstance: echarts.ECharts | null = null
    
    const currentView = ref<ViewType>(props.viewType)
    
    // 处理视图类型变更
    const handleViewChange = (view: string | number | boolean | undefined) => {
      if (typeof view === 'string' && (view === 'amount' || view === 'count' || view === 'savings')) {
        emit('view-change', view)
      }
    }
    
    // 根据选择的视图类型获取Y轴数据
    const getSeriesData = computed(() => {
      return props.chartData.map(item => {
        if (currentView.value === 'amount') {
          return item.amount
        } else if (currentView.value === 'count') {
          return item.count
        } else {
          return item.savings
        }
      })
    })
    
    // 获取X轴数据（日期）
    const getXAxisData = computed(() => {
      return props.chartData.map(item => {
        // 将日期格式化为更友好的显示
        const date = new Date(item.date)
        return `${date.getMonth() + 1}/${date.getDate()}`
      })
    })
    
    // 获取视图标题
    const getViewTitle = computed(() => {
      switch (currentView.value) {
        case 'amount':
          return '采购金额趋势'
        case 'count':
          return '采购单量趋势'
        case 'savings':
          return '节约成本趋势'
        default:
          return '采购趋势'
      }
    })
    
    // 获取Y轴单位
    const getYAxisUnit = computed(() => {
      switch (currentView.value) {
        case 'amount':
          return '元'
        case 'count':
          return '单'
        case 'savings':
          return '元'
        default:
          return ''
      }
    })
    
    // 初始化图表
    const initChart = () => {
      if (!chartRef.value) return
      
      // 创建图表实例
      chartInstance = echarts.init(chartRef.value)
      
      // 更新图表
      updateChart()
      
      // 监听窗口大小变化，调整图表大小
      window.addEventListener('resize', handleResize)
    }
    
    // 更新图表
    const updateChart = () => {
      if (!chartInstance) return
      
      const colorMap = {
        amount: ['#409EFF', '#a8daff'],
        count: ['#67C23A', '#c0f0a5'],
        savings: ['#E6A23C', '#ffd27f']
      }
      
      // 图表配置选项
      const option = {
        title: {
          text: getViewTitle.value,
          left: 'center',
          top: 0,
          textStyle: {
            color: '#303133',
            fontSize: 16,
            fontWeight: 'normal'
          }
        },
        tooltip: {
          trigger: 'axis',
          formatter: (params: any) => {
            const data = params[0]
            let unit = getYAxisUnit.value
            return `${data.name}<br/>${data.seriesName}: ${data.value.toLocaleString()} ${unit}`
          }
        },
        grid: {
          top: 60,
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: getXAxisData.value,
          axisLine: {
            lineStyle: {
              color: '#DCDFE6'
            }
          },
          axisTick: {
            show: false
          },
          axisLabel: {
            color: '#606266'
          }
        },
        yAxis: {
          type: 'value',
          axisLine: {
            show: false
          },
          axisTick: {
            show: false
          },
          splitLine: {
            lineStyle: {
              color: '#EBEEF5',
              type: 'dashed'
            }
          },
          axisLabel: {
            color: '#606266',
            formatter: (value: number) => {
              if (currentView.value === 'amount' || currentView.value === 'savings') {
                if (value >= 10000) {
                  return (value / 10000).toFixed(1) + '万'
                }
                return value.toLocaleString()
              }
              return value
            }
          }
        },
        series: [
          {
            name: getViewTitle.value,
            type: 'line',
            data: getSeriesData.value,
            smooth: true,
            symbol: 'emptyCircle',
            symbolSize: 6,
            itemStyle: {
              color: colorMap[currentView.value][0]
            },
            lineStyle: {
              width: 3,
              color: colorMap[currentView.value][0]
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: colorMap[currentView.value][0]
                },
                {
                  offset: 1,
                  color: 'rgba(255, 255, 255, 0.2)'
                }
              ])
            }
          }
        ],
        dataZoom: [
          {
            type: 'inside',
            start: 0,
            end: 100
          }
        ]
      }
      
      // 设置图表选项
      chartInstance.setOption(option)
    }
    
    // 处理窗口大小变化
    const handleResize = () => {
      if (chartInstance) {
        chartInstance.resize()
      }
    }
    
    // 监听 props 变化
    watch(
      () => [props.chartData, currentView.value, props.viewType],
      () => {
        if (props.viewType !== currentView.value) {
          currentView.value = props.viewType
        }
        if (!props.loading) {
          updateChart()
        }
      },
      { deep: true }
    )
    
    // 监听加载状态变化
    watch(
      () => props.loading,
      (newVal) => {
        if (!newVal && chartInstance) {
          updateChart()
        }
      }
    )
    
    // 组件挂载时初始化图表
    onMounted(() => {
      if (!props.loading) {
        initChart()
      }
    })
    
    // 组件销毁前清理资源
    onBeforeUnmount(() => {
      if (chartInstance) {
        chartInstance.dispose()
        chartInstance = null
      }
      window.removeEventListener('resize', handleResize)
    })
    
    return {
      chartRef,
      currentView,
      handleViewChange
    }
  }
})
</script>

<style scoped lang="scss">
.trend-chart-card {
  background-color: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  border-radius: 8px;
  padding: 20px;
  height: 450px;
  display: flex;
  flex-direction: column;
  
  .chart-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    flex-shrink: 0;
    
    h3 {
      margin: 0;
      font-size: 16px;
      font-weight: 600;
      color: #303133;
    }
  }
  
  .chart-container {
    position: relative;
    flex: 1;
    width: 100%;
    height: 100%;
    
    .chart-wrapper {
      height: 100%;
      width: 100%;
    }
    
    .chart-loading {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(255, 255, 255, 0.8);
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 20px;
      
      .el-skeleton {
        width: 100%;
      }
    }
  }
}

@media screen and (max-width: 768px) {
  .trend-chart-card {
    height: 350px;
    
    .chart-header {
      flex-direction: column;
      align-items: flex-start;
      
      h3 {
        margin-bottom: 10px;
      }
      
      .view-controls {
        width: 100%;
        display: flex;
        justify-content: center;
      }
    }
  }
}
</style> 